from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import json
from typing import Any
from app.core.config import settings
from app.api import auth, conversation, chat
from app.db.base import Base, engine
from app.db.init_data import init_default_data
from app.db.base import get_db_context
import uvicorn

# 创建数据库表
Base.metadata.create_all(bind=engine)

# 初始化默认数据
with get_db_context() as db:
    init_default_data(db)

class CustomJSONResponse(JSONResponse):
    def render(self, content: Any) -> bytes:
        def convert_large_numbers(obj):
            if isinstance(obj, int) and abs(obj) > 2 ** 53 - 1:
                return str(obj)
            elif isinstance(obj, dict):
                return {k: convert_large_numbers(v) for k, v in obj.items()}
            elif isinstance(obj, (list, tuple)):
                return [convert_large_numbers(item) for item in obj]
            return obj

        content = convert_large_numbers(content)
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=None,
            separators=(",", ":"),
        ).encode("utf-8")

app = FastAPI(
    title=settings.PROJECT_NAME,
    version=settings.VERSION,
    openapi_url=f"{settings.API_V1_STR}/openapi.json",
    default_response_class=CustomJSONResponse
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["认证"])
app.include_router(conversation.router, prefix=f"{settings.API_V1_STR}/conversations", tags=["对话"])
app.include_router(chat.router, prefix=f"{settings.API_V1_STR}/chat", tags=["聊天"])

@app.get("/")
async def root():
    return {
        "message": "欢迎使用AI对话智能体API",
        "version": settings.VERSION
    }

if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True
    ) 